package com.view.mediator
{
	import com.ApplicationFacade;
	import com.view.component.MainView;
	import com.model.vo.FormSaveVO;
	//import com.model.proxy.FormSaveProxy;
	import com.model.proxy.FormSaveFake;

	import flash.events.Event;
	import mx.controls.Alert;

	import org.puremvc.as3.multicore.utilities.statemachine.StateMachine;
	import org.puremvc.as3.multicore.interfaces.IMediator;
	import org.puremvc.as3.multicore.interfaces.INotification;
	import org.puremvc.as3.multicore.patterns.mediator.Mediator;

	public class MainViewValidator extends Mediator implements IMediator
	{
		public static const NAME:String='MainViewValidator';

		public static const FORM_VALIDATION:String='FormValidation';

		private var collectedVOS:Array=new Array();
		private var invalidFields:Array=new Array();
		private var formsToValidate:Array=new Array();
		private var errors:Array=new Array();
		private var countFormsToValidate:int;
		private var countValidForms:int=0;
		private var alertMessage:String="";
		private var workSaved:Boolean=false;

		//private var formSaveProxy:FormSaveProxy;
		private var formSaveProxy:FormSaveFake;
		private var formSaveVO:FormSaveVO;

		public function MainViewValidator(viewComponent:Object)
		{
			super(NAME, viewComponent);
		}

		protected function get mainView():MainView
		{
			return viewComponent as MainView;
		}

		override public function onRegister():void
		{
			mainView.addEventListener(MainView.SUBMIT_FORM, onSubmitForm);
			mainView.addEventListener(MainView.RESET_FORM, onResetForm);
			mainView.addEventListener(MainView.LOGOUT, onLogout);

			//facade.registerProxy(new FormSaveProxy());
			facade.registerProxy(new FormSaveFake());
			formSaveVO=new FormSaveVO();
			formsToValidate=formSaveVO.viewsToCheck;
			countFormsToValidate=formSaveVO.viewsToCheck.length;
		}

		override public function listNotificationInterests():Array
		{
			return [FORM_VALIDATION, ApplicationFacade.SHOW_THANKS, ApplicationFacade.SHOW_FAILED, ApplicationFacade.SAVE_FORM];
		}

		override public function handleNotification(note:INotification):void
		{
			switch (note.getName())
			{
				case FORM_VALIDATION:
					var formName:String=note.getType();
					var validationObject:Object=new Object();
					validationObject[formName]=note.getBody();
					isFormValidated(validationObject, formName);
				break;
				case ApplicationFacade.SAVE_FORM:
					sendVOToProxy();
					break;
				case ApplicationFacade.SHOW_THANKS:
					showThanks(note.getBody());
					break;
				case ApplicationFacade.SHOW_FAILED:
					showFailed(note.getBody());
					break;
			}
		}
		protected function isFormValidated(validationObject:Object,formName:String):void{
			collectVOS(validationObject, formName);
			if (countValidForms == countFormsToValidate)
			{
				sendNotification(StateMachine.ACTION, "VALIDATED", ApplicationFacade.VALIDATED);
			}
			else
			{
				collectErrors(validationObject, formName);
			}
		}
		protected function collectVOS(validationObject:Object, formName:String):void
		{
			collectedVOS[formName]=validationObject[formName]["vo"].mapValuesToArray();
			if (formsToValidate.indexOf(formName) != -1)
			{
				formsToValidate.splice(formsToValidate.indexOf(formName), 1);
			}
			if (validationObject[formName]["valid"])
			{
				countValidForms++;
			}
		}

		protected function collectErrors(validationObject:Object, formName:String):void
		{
			alertMessage="";
			invalidFields[formName]=validationObject[formName]["errors"];
			if (formsToValidate.length > 0)
			{
				alertMessage=formsToValidate.toString() + ": missing data for validation\n\n";
			}
			for (var f:String in invalidFields)
			{
				if (invalidFields[f] != "")
				{
					alertMessage+=f + ": required fields: " + invalidFields[f] + "\n";
					if (errors.indexOf(f) == -1)
					{
						errors.push(f);
					}
				}
				else
				{
					alertMessage+=f + ":  valid  \n";
					if (errors.indexOf(f) != -1)
					{
						errors.splice(errors.indexOf(f), 1);
					}
				}
			}
			mainView.alertMessages.text=alertMessage;
			mainView.alertMessages.visible=true;
		}

		protected function sendVOToProxy():void
		{
			//formSaveProxy=facade.retrieveProxy(FormSaveProxy.NAME) as FormSaveProxy;
			formSaveProxy=facade.retrieveProxy(FormSaveFake.NAME) as FormSaveFake;
			formSaveProxy.saveData(collectedVOS);
			mainView.submitButton.enabled=false;
			collectedVOS=[];
		}

		protected function onSubmitForm(event:Event):void
		{
			workSaved=false;
			countValidForms=0;
			sendNotification(StateMachine.ACTION, "SUBMITED", ApplicationFacade.SUBMITED);
			sendNotification(ApplicationFacade.VALIDATE_FORMS);
		}

		protected function onResetForm(event:Event):void
		{
			restoreDefault();
			sendNotification(ApplicationFacade.RESET_FORMS);
			sendNotification(StateMachine.ACTION, "COLLECT", ApplicationFacade.COLLECT);
		}

		protected function onLogout(event:Event):void
		{
			mainView.mainViewStack.selectedIndex=0;
			restoreDefault();
			sendNotification(StateMachine.ACTION, workSaved, ApplicationFacade.LOGOUT);
		}

		protected function showThanks(thanks:Object):void
		{
			workSaved=true;
			mainView.alertMessages.visible=true;
			mainView.alertMessages.text="Thank you for saving this weird form.\n\n" + thanks.toString();
			sendNotification(StateMachine.ACTION, "COLLECT", ApplicationFacade.COLLECT);
		}

		protected function showFailed(failed:Object):void
		{
			workSaved=false;
			restoreDefault();
			mainView.alertMessages.visible=true;
			mainView.alertMessages.text="FAILED:\n" + failed.toString();
			sendNotification(StateMachine.ACTION, "COLLECT", ApplicationFacade.COLLECT);
		}

		protected function restoreDefault():void
		{
			mainView.submitButton.enabled=true;
			mainView.alertMessages.visible=false;
			mainView.alertMessages.text="";
			alertMessage="";
			formsToValidate=formSaveVO.viewsToCheck;
			countValidForms=0;
			invalidFields=[];
			errors=[];
			workSaved=false;
		}
	}
}